<template>
  <div
    v-loading.fullscreen="load__"
    element-loading-text="拼命上传中……"
    element-loading-spinner="el-icon-loading"
    element-loading-background="rgba(255, 255, 255, 0.8)"
    class="uploadFile"
  >
    <div class="uploadBtn">
      <el-button v-show="fileList.length < limitSize" type="primary" size="mini" @click="startUpload">
        <input type="file" :accept="ipModel ? 'image/*,application/pdf' : ''" multiple="multiple" @change="startUpload(0)">{{ name }}
      </el-button>
      <a v-if="withDownload||downloadModelUrl" @click="downLoadFunc">下载模板</a>
      <span v-if="tips">{{ tips }}</span>
    </div>
    <ul v-if="noImmediately" :style="'width:' + width + 'px'">
      <li v-for="(item,index) in fileList" :key="index">{{ item.name }} <i class="el-icon-close" @click="deleteFile(index)" /></li>
    </ul>
    <ul v-else :style="'width:' + width + 'px'">
      <li v-for="(item,index) in fileList" :key="index">
        <a :href="item.fileUrl||''" :title="item.fileName" target="_blank">
          <p :class="{completed: !item.showProgress}"><i class="el-icon-document" /> {{ item.fileName }}</p>
          <el-progress v-show="item.showProgress" :stroke-width="8" :percentage="item.progress" :show-text="false" />
        </a>
        <i class="el-icon-close" @click="deleteFile(index)" />
      </li>
    </ul>
  </div>
</template>

<script>
import axios from 'axios'
import { getToken, setToken } from '@/utils/auth'
export default {
  name: 'FileUpLoad',
  props: {
    noImmediately: {
      type: Boolean,
      default: false
    },
    downloadModelUrl: {
      type: String,
      default: ''
    },
    withDownload: {
      type: Boolean,
      default: false
    },

    ipModel: {
      type: Boolean,
      default: false
    },

    width: {
      type: String,
      default: ''
    },
    errDuration: {
      type: Number,
      default: 3000
    },
    name: {
      type: String,
      default: '选择文件上传'
    },
    value: {
      type: String,
      default: ''
    },
    mini: {
      type: Boolean,
      default: false
    },
    large: {
      type: Boolean,
      default: false
    },
    limitType: {
      type: String,
      default: 'jpeg, png, pdf, jpg'
    },
    maxFileSize: {
      type: Number,
      default: 5
    },
    limitSize: {
      type: Number,
      default: 5
    },
    tips: {
      type: String,
      default: ''
    },
    data: {
      type: Object,
      default: () => {
        return {}
      }
    },
    uploadUrl: {
      type: String,
      default: ''
    },
    file: {
      type: String,
      default: 'file'
    },
    loading: {
      type: Boolean,
      default: false
    }
  },

  data() {
    return {
      load__: false,
      fileList: [],
      currentViewImg: '',
      localInx: 0
    }
  },

  watch: {
    value(newV) {
      this.reset()
    }
  },
  mounted() {
    this.reset()
  },

  methods: {
    reset() {
      if (this.value) {
        this.fileList.splice(0, this.fileList.length)
        const newList = this.evil(this.value)
        newList.forEach(e => {
          this.fileList.push({
            fileUrl: e.url,
            showProgress: false,
            progress: 0,
            fileName: e.name || e.url.substr(e.url.lastIndexOf('/') + 1, e.url.length)
          })
        })
      } else {
        this.fileList = []
      }
    },

    deleteFile(index) {
      const file = this.fileList[index]
      this.fileList.splice(index, 1)
      if (!this.noImmediately) {
        this.$emit('delete', { url: file.fileUrl, name: file.fileName })
        this.exportFilesValue()
      }
    },

    startUpload() {
      const file = event.target
      let passed = true
      for (const f of file.files) {
        if (f.size / 1024 / 1024 > this.maxFileSize) {
          this.$message.error(`上传的文件不能大于${this.maxFileSize}M`)
          file.value = ''
          passed = false
          return
        }

        if (this.limitType) {
          const exe = f.name.substr(f.name.lastIndexOf('.') + 1, f.name.length).toUpperCase()
          if (!this.limitType.toUpperCase().includes(exe)) {
            passed = false
            this.$message.warning(`仅可上传${this.limitType}格式的文件`)
            file.value = ''
            return
          }
        }
      }

      if (passed) {
        if (this.noImmediately) {
          for (const f of file.files) {
            this.fileList.push(f)
          }
        } else {
          for (const f of file.files) {
            if (this.limitSize > this.fileList.length) {
              const fileObj = {
                fileUrl: '',
                showProgress: true,
                progress: 0,
                fileName: f.name,
                failed: false
              }
              this.fileList.push(fileObj)
              this.uploadFile(fileObj, f)
            }
          }
        }
        file.value = ''
      }
    },
    clearFileList() {
      this.fileList.splice(0, this.fileList.length)
    },
    uploadFile(fileObj, file) {
      const formData = new FormData()
      formData.append(this.file, file)
      console.log(formData)
      for (const k in this.data) {
        formData.append([k], this.data[k])
      }
      const time__ = Date.now()
      if (this.loading) { this.load__ = true }
      try {
        axios({
          url: this.uploadUrl || process.env.FILEUPURL,
          method: 'post',
          timeout: 300000,
          onUploadProgress: function(progressEvent) { // 原生获取上传进度的事件
            if (progressEvent.lengthComputable) {
              fileObj.progress = parseInt(progressEvent.loaded / progressEvent.total * 100)
            }
          },
          headers: { 'Authorization': 'bearer ' + getToken() || '', 'Content-Type': 'application/json' },
          data: formData,
          withCredentials: true
        }).then(res => {
          console.log(res)
          if (this.loading) { // 加载动画
            if (Date.now() - time__ < 200) {
              setTimeout(() => {
                this.load__ = false
              }, 300)
            } else {
              this.load__ = false
            }
          }
          if (res.headers.authorization) {
            const token = res.headers.authorization || ''
            setToken(token)
          }
          if (res.data.success || res.data.code * 1 === 0) {
            fileObj.fileUrl = res.data.data
            fileObj.showProgress = false
            this.$emit('change', { url: fileObj.fileUrl, name: fileObj.fileName })
            this.$message({
              message: '上传成功',
              type: 'success'
            })
            this.exportFilesValue()
          } else {
            this.$message({
              message: res.data.errMsg || '上传失败',
              type: 'error',
              duration: this.errDuration
            })
            fileObj.failed = true
            this.fileList = this.fileList.filter(e => {
              return !e.failed
            })
          }
        })
      } catch (e) {
        this.$message.warning('接口请求失败')
      }
    },

    startHandUpload() {
      if (this.fileList.length > 0) {
        this.localInx = 0
        console.log(this.fileList)
        for (const f of this.fileList) {
          this.handUpLoad(f)
        }
      } else {
        this.$message.warning('请选择文件')
      }
    },

    handUpLoad(file) {
      console.log(file)
      const formData = new FormData()
      formData.append(this.file, file)
      console.log(formData)
      for (const k in this.data) {
        formData.append([k], this.data[k])
      }
      const loading = this.$loading({
        lock: true,
        text: '上传中...',
        spinner: 'el-icon-loading',
        background: 'rgba(255, 255, 255, 0.6)'
      })
      try {
        axios({
          url: this.uploadUrl || process.env.FILEUPURL,
          method: 'post',
          timeout: 300000,
          headers: { 'Authorization': 'bearer ' + getToken() || '', 'Content-Type': 'application/json' },
          data: formData,
          withCredentials: true
        }).then(res => {
          loading.close()
          if (res.headers.authorization) {
            const token = res.headers.authorization || ''
            setToken(token)
          }
          if (res.data.success) {
            this.localInx++
            if (this.localInx >= this.fileList.length - 1) {
              this.$emit('change')
              this.fileList.length = 0
            }
          } else {
            this.$message({
              message: res.data.errMsg,
              type: 'error',
              duration: this.errDuration
            })
          }
        })
      } catch (e) {
        this.$message.warning('接口请求失败')
      }
    },

    downLoadFunc() {
      if (this.downloadModelUrl !== undefined) {
        const a = document.createElement('a')
        a.setAttribute('href', this.downloadModelUrl)
        a.setAttribute('target', '_blank')
        a.setAttribute('id', 'a____startTelMedicine')
        // 防止反复添加
        if (document.getElementById('a____startTelMedicine')) {
          document.body.removeChild(document.getElementById('a____startTelMedicine'))
        }
        document.body.appendChild(a)
        a.click()
      }
      this.$emit('downloadMode')
    },

    exportFilesValue() {
      const noComplete = this.fileList.find(e => {
        return e.showProgress
      })
      if (noComplete) {
        setTimeout(() => {
          this.exportFilesValue()
        }, 200)
      } else {
        const files = []
        this.fileList.forEach(e => {
          files.push({ url: e.fileUrl, name: e.fileName })
        })
        this.$emit('input', JSON.stringify(files))
      }
    },

    evil(fn) {
      var Fn = Function
      return new Fn('return ' + fn)()
    }
  }
}

</script>
<style scoped lang='scss'>
  ul{
    li{height:40px;position:relative;background: #f5f5f5;line-height:40px;margin-bottom: 10px;font-size:13px;padding:0 8px;white-space: nowrap;overflow: hidden;text-overflow:ellipsis;
      &>a{width: 94%;display: block;height: 40px}
      p{float:left; width: 35%;text-overflow: ellipsis; overflow: hidden; white-space: nowrap; color: #666}
      p.completed{width: 100%}
      .el-progress{width:63%;display: inline-block; top: -1px; position: relative; margin: 0 2px}
      > i:last-child{position:absolute;right:5px;top:0px;cursor:pointer;font-size:14px;color:#999;line-height:40px}
    }
  }
  .uploadBtn{margin-bottom: 10px}
  .uploadBtn span{color: #999; font-size: 12px; margin-top: -10px;transform:scale(0.9,0.9);display: inline-block}
  .uploadBtn a{color: #5584FF;font-size: 12px;text-decoration: underline;position: relative;left: 2px;top: 1px;cursor: pointer}
  .el-button{position: relative;cursor: pointer}
  .el-button input{position:absolute;left:0;top:0;width:100%;height:100%;opacity:0;z-index:10;cursor:pointer}
</style>
